package gwtadmin.server;

import gwtadmin.client.GreetingService;
import gwtadmin.client.WsdlTreeInfo;
import gwtadmin.client.wsdltree.QName;
import gwtadmin.client.wsdltree.WtBinding;
import gwtadmin.client.wsdltree.WtMessage;
import gwtadmin.client.wsdltree.WtOperation;
import gwtadmin.client.wsdltree.WtPolicy;
import gwtadmin.client.wsdltree.WtPort;
import gwtadmin.client.wsdltree.WtPortType;
import gwtadmin.client.wsdltree.WtService;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

/**
 * The server side implementation of the RPC service.
 */
@SuppressWarnings("serial")
public class GreetingServiceImpl extends RemoteServiceServlet implements
		GreetingService {

	private ServiceRegistry registry;
	
	public GreetingServiceImpl() {
		super();
		registry = new ServiceRegistry("localhost:9001");
	}
	
	public GreetingServiceImpl(ServiceRegistry serviceRegistry) {
		super();
		registry = serviceRegistry;
	}
	
	/**
	 * Checks for Service Registry is started.
	 * 
	 * @return returns true The Service Registry is started.
	 */
	@Override
	public boolean isRegistryUp() {
		return registry.isRegistryUp();
	}
	
	/**
	 * Retrieving list of WSDL files in Service Registry.
	 * 
	 * @return returns list in XML format.
	 */
	@Override
	public String getWsdlList() {
		return registry.getWsdlList();
	}
	
	/**
	 * Retrieving list of WSDL files in Service Registry.
	 * 
	 * @return returns list in XML format.
	 */
	@Override
	public String getWsdlList(boolean byPortType, String name, String namespace) {
		if (byPortType)
			return registry.getWsdlListPortType(name, namespace);
		else
			return registry.getWsdlListService(name, namespace);
	}

	/**
	 * Returns content of WSDL file.
	 * 
	 * @param fileName - Name of file which content is needed.
	 * @return Content of WSDL file.
	 */
	@Override
	public String getWsdlFile(String fileName) {
		return registry.getWsdlFile(fileName);
	}
	
	/**
	 * Removes WSDL file from Service Registry.
	 * 
	 * @param fileName - Name of file for remove.
	 * @return Returns true if success and false otherwise.
	 */
	@Override
	public boolean removeWsdlFile(String fileName) {
		return registry.removeWsdlFile(fileName);
	}
	
	/**
	 * Puts WSDL to Service Registry.
	 * 
	 * @param fileName - WSDL will be saved under this name.
	 * @param wsdl - content of WSDL file.
	 * @return Returns true if success and false otherwise.
	 */
	@Override
	public boolean uploadWsdlFile(String fileName, String wsdl) {
		return registry.uploadWsdlFile(fileName, wsdl);
	}

	/**
	 * Builds tree of services in registry.
	 * 
	 * @return Returns object WsdlTreeInfo, which contains tree that representing services in registry.
	 */
	@Override
	public WsdlTreeInfo getWsdlTree() {
		
		QName qFac = new QName(null, "http://service.dynamic.samples.swordfish.eclipse.org/");

		WtMessage msgSearch = new WtMessage(qFac.create("searchFlights"));
		WtMessage msgSearchResp = new WtMessage(qFac.create("searchFlightsResponse"));
		
		msgSearch.addPart(qFac.create("parameters"), "tns:searchFlights");
		msgSearchResp.addPart(qFac.create("parameters"), "tns:searchFlightsResponse");
		
		WtOperation opSearch = new WtOperation(qFac.create("searchFlights"), msgSearch, msgSearchResp, null);
		
		WtOperation[] operations = { opSearch };
		WtPortType portType = new WtPortType(qFac.create("FlightService"), "http://localhost:9001/registry/wsdl/FlightServiceImpl.wsdl", operations);
		
		WtBinding bind = new WtBinding(qFac.create("FlightServiceImplSoapBinding"), portType);
		
		WtPort port = new WtPort(qFac.create("FlightServiceImplPort"), "http://localhost:9091/flights/", bind);
		
		WtPort[] ports = { port };
		WtService svc = new WtService(qFac.create("FlightServiceImpl"), "http://localhost:9001/registry/wsdl/FlightServiceImpl.wsdl", ports);
		
		WsdlTreeInfo wsdl = new WsdlTreeInfo();
		wsdl.addService(svc);
		wsdl.addBinding(bind);
		wsdl.addPortType(portType);
		
		//////////////////////////////////////////////////////////////////////////////////////
		
		qFac = new QName(null, "http://services.sopware.org/ExampleURI");
		
		WtMessage notifResponseMsg = new WtMessage(qFac.create("notifResponseMsg"));
		WtMessage oneWayRequestMsg = new WtMessage(qFac.create("oneWayRequestMsg"));
		WtMessage opRequestMsg = new WtMessage(qFac.create("opRequestMsg"));
		WtMessage opResponseMsg = new WtMessage(qFac.create("opResponseMsg"));
		WtMessage opFaultMsg = new WtMessage(qFac.create("opFaultMsg"));
		
		notifResponseMsg.addPart(qFac.create("body"), "tns:NotificationResponse");
		oneWayRequestMsg.addPart(qFac.create("body"), "tns:OneWayRequest");
		opRequestMsg.addPart(qFac.create("body"), "tns:OperationRequest");
		opResponseMsg.addPart(qFac.create("body"), "tns:OperationResponse");
		opFaultMsg.addPart(qFac.create("error"), "tns:OperationFault");
		
		WtMessage[] msgFarray = {opFaultMsg};
		WtOperation requestResponseOperation = new WtOperation(qFac.create("RequestResponseOperation"), opRequestMsg, opResponseMsg, msgFarray);
		WtOperation notificationOperation = new WtOperation(qFac.create("NotificationOperation"), null, notifResponseMsg, null);
		WtOperation oneWayOperation = new WtOperation(qFac.create("OneWayOperation"), oneWayRequestMsg, null, null);
		
		WtOperation[] arrOps = { requestResponseOperation, notificationOperation, oneWayOperation };
		WtPortType ptExampleService = new WtPortType(qFac.create("ExampleService"), "http://localhost:9001/registry/wsdl/ExampleService.sdx", arrOps);
		
		
		WtBinding bindlocalhostBinding = new WtBinding(qFac.create("localhostBinding"), ptExampleService);
		WtBinding bindjmsBinding = new WtBinding(qFac.create("localhost_jmsBinding"), ptExampleService);
		
		WtPort portEsp = new WtPort(qFac.create("localhost"), "http://localhost:8888/soap/ExampleServiceProvider", bindlocalhostBinding);
		WtPort portjmsTopic = new WtPort(qFac.create("jmsTopic"), "tcp://127.0.0.1:16400", bindjmsBinding);
		
		WtPort[] portsEsp = { portEsp, portjmsTopic };
		WtService svcExampleServiceProvider = new WtService(qFac.create("ExampleServiceProvider"), "http://localhost:9001/registry/wsdl/ExampleService.spdx", portsEsp);

		svcExampleServiceProvider.addPolicy(new WtPolicy(new QName("Compression"), "http://localhost:9001/registry/policy/Compression"));
		
		wsdl.addService(svcExampleServiceProvider);

		return wsdl;
	}
}
